<?php

/**
 * Base maintenance public class
 *
 * PHP version 5
 *
 * Copyright © 2013 François Cero
 *
 * This file is part of Galette (http://galette.tuxfamily.org).
 *
 * Plugin MySqlsave is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
 *
 * @category  Plugins
 * @package   MySqlsave
 *
 * @author    François Cero <cerol@laposte point net>
 * @copyright 2013 François Cero
 * @license   http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
 * @version   0.1
 * @link      http://galette.tuxfamily.org
 * @since     Available since 0.7
 */
/**
 * Sauvegarde MySQL
 *
 * @package	BackupMySQL
 * @author	Benoit Asselin <contact@ab-d.fr>
 * @version	backup.php, 2013/01/13
 * @link	http://www.ab-d.fr/
 * http://blog.site-web-creation.net/mysql-backup/
 */

/**
 * Classe Sauvegarde MySQL
 */
class BackupMySQL extends mysqli {
	
	/**
	 * Dossier des fichiers de sauvegardes
	 * @var string
	 */
	protected $dossier;
	
	/**
	 * Nom du fichier
	 * @var string
	 */
	protected $nom_fichier;
	
	/**
	 * Ressource du fichier GZip
	 * @var ressource
	 */
	protected $gz_fichier;
	
	
	/**
	 * Constructeur
	 * @param array $options
	 */
	public function __construct($options = array()) {
		global  $msg;
		$msg = "";
		$default = array(
			'host' => ini_get('mysqli.default_host'),
			'username' => ini_get('mysqli.default_user'),
			'passwd' => ini_get('mysqli.default_pw'),
			'dbname' => '',
			'port' => ini_get('mysqli.default_port'),
			'socket' => ini_get('mysqli.default_socket'),
			// autres options
			'dossier' => './',
			'nbr_fichiers' => 50,
			'nom_fichier' => NAME_DB,
			);
		$options = array_merge($default, $options);
		extract($options);
		
		// Connexion de la connexion DB
		@parent::__construct($host, $username, $passwd, $dbname, $port, $socket);
		mysqli_set_charset($this, "utf8");  

		if($this->connect_error) {
			$msg=(_T("SAVE.SQL ERROR").'(' . $this->connect_errno . ') '. $this->connect_error);
			return $msg;
		}
		
		// Controle du dossier
		$this->dossier = $dossier;
		if(!is_dir($this->dossier)) {
			$msg=(_T("SAVE.DIR ERROR").'&quot;' . htmlspecialchars($this->dossier) . '&quot;');
			return $msg;
		}
		
		// Controle du fichier
		$this->nom_fichier = $nom_fichier . date('Ymd-His') . '.sql.gz';
		$this->gz_fichier = @gzopen($this->dossier . $this->nom_fichier, 'w');
		if(!$this->gz_fichier) {
			$msg=(_T("SAVE.FILE ERROR").'&quot;' . htmlspecialchars($this->nom_fichier) . '&quot;');
			return $msg;
		}
		
		// Demarrage du traitement
		//$this->sauvegarder();
		$this->purger_fichiers($nbr_fichiers);
	}
	


	/**
	 * Message d'information ( commenter le "echo" pour rendre le script invisible )
	 * @param string $message HTML
	 */
	public function message($message = '&nbsp;') {
		echo '<p style="padding:0; margin:1px 10px; font-family:sans-serif;">'. $message .'</p>';
	}
	public function messageNoNL($message = '&nbsp;') {
		echo '<p style="padding:0; margin:0px 2px; font-family:sans-serif; display:inline">'. $message .'</>';
	}
	/**
	 * Protection des quot SQL
	 * @param string $string
	 * @return string
	 */
	public function insert_clean($string) {
				// Ne pas changer l'ordre du tableau !!!
				$s1 = array( "\\"	, "'"	, "\r", "\n", );
				$s2 = array( "\\\\"	, "''"	, '\r', '\n', );
				return str_replace($s1, $s2, $string);
	}
	
	/**
	 * Sauvegarder les tables
	 */
	public function sauvegarder() {
		//$this->message('Sauvegarde...');
		global $listtables;
		global $namesav;
		global $messsav;
		$sql  = '--' ."\n";
		$sql .= '-- '. $this->nom_fichier ."\n";
		$sql .= 'SET FOREIGN_KEY_CHECKS=0;'."\n";
		$sql .= 'SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";'."\n";
		gzwrite($this->gz_fichier, $sql);
		
		// Liste les tables
		$result_tables = $this->query('SHOW TABLE STATUS');
		if($result_tables && $result_tables->num_rows) {
			while($obj_table = $result_tables->fetch_object()) {
				$listtables.=(htmlspecialchars($obj_table->{'Name'}.' - ' ));
				
				// DROP ...
				$sql  = "\n\n";
				$sql .= 'DROP TABLE IF EXISTS `'. $obj_table->{'Name'} .'`' .";\n";

				// CREATE ...
				$result_create = $this->query('SHOW CREATE TABLE `'. $obj_table->{'Name'} .'`');

				if($result_create && $result_create->num_rows) {
					$obj_create = $result_create->fetch_object();
					$sql .= $obj_create->{'Create Table'} .";\n";
					$result_create->free_result();
				}

				// INSERT ...
				
				$result_insert = $this->query('SELECT * FROM `'. $obj_table->{'Name'} .'`');
			
				if($result_insert && $result_insert->num_rows) {
				

					$sql .= "\n";
					while($obj_insert = $result_insert->fetch_object()) {
					
						$virgule = false;
						
						$sql .= 'INSERT INTO `'. $obj_table->{'Name'} .'` VALUES (';
						foreach($obj_insert as $val) {
							$sql .= ($virgule ? ',' : '');
							if(is_null($val)) {
								$sql .= 'NULL';
							} else {
									$sql .= '\''. $this->insert_clean($val) . '\'';
							}
							$virgule = true;
						} // for
						
						$sql .= ')' .";\n";
						
					} // while
					$result_insert->free_result();
				}
				gzwrite($this->gz_fichier, $sql);
			} // while
			$result_tables->free_result();
		}
		$sql = 'SET FOREIGN_KEY_CHECKS=1;'."\n";
		gzwrite($this->gz_fichier, $sql);
		gzclose($this->gz_fichier);
		$namesav= htmlspecialchars($this->nom_fichier);
		$messsav.=('<strong style="color:green;"><br />' . $namesav . '</strong>');
		
		$messsav.=('<br />La sauvegarde se trouve dans le fichier : '.$namesav);

		$messsav.=(' <br /><b>Pour le télécharger sur votre ordinateur :</b><br /><span style="color:white;background-color: yellow;"><a href=backups/'.$namesav.'>CLIC DROIT sur cette ligne et enregistrer la cible </a></span><br />');

	}
	
	/**
	 * delete old backup files
	 * @param int $nbr_fichiers_max Number of undeleted old backups files 
	 */
	public function purger_fichiers($nbr_fichiers_max) {
		global $messprune;
		//$this->message();
		$messprune=('Purge des anciens fichiers. Seuls les '.$nbr_fichiers_max.' derniers fichiers sont conservés. <br />');
		$fichiers = array();
		
		// On recupere le nom des fichiers gz
		if($dossier = dir($this->dossier)) {
			while(false !== ($fichier = $dossier->read())) {
				if($fichier != '.' && $fichier != '..') {
					if(is_dir($this->dossier . $fichier)) {
						// Ceci est un dossier ( et non un fichier )
						continue;
					} else {
						// On ne prend que les fichiers se terminant par ".gz"
						if(preg_match('/\.gz$/i', $fichier)) {
							$fichiers[] = $fichier;
						}
					}
				}
			} // while
			$dossier->close();
		}
		
		// we delete old files 
		$nbr_fichiers_total = count($fichiers);
		if($nbr_fichiers_total >= $nbr_fichiers_max) {
			// Inverser l'ordre des fichiers gz pour ne pas supprimer les derniers fichiers
			rsort($fichiers);
			
			// Deleting...
			for($i = $nbr_fichiers_max; $i < $nbr_fichiers_total; $i++) {
				$messprune.= ('<strong style="color:red;"><br />' . htmlspecialchars($fichiers[$i]) . '</strong>');
				unlink($this->dossier . $fichiers[$i]);
			}
		}
		$messprune.= ('<br />Purge termin&eacute;e !');

	}
			
}
?>
